package com.dog.basics.security.controller;

import java.io.InputStream;
import java.util.Map;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.dog.basics.common.util.R;
import com.dog.basics.common.util.RedisUtil;
import com.dog.basics.security.constants.SecurityConstants;
import com.dog.basics.security.util.VerifyImageUtil;
import com.dog.basics.security.util.WordCodeEnum;
import com.dog.basics.security.util.WordCodeTemplatesEnum;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.cache.CacheManager;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import springfox.documentation.annotations.ApiIgnore;

/**
 * 登录相关
 *
 * @author dog
 */
@RestController
@AllArgsConstructor
@ApiIgnore
@Log4j2
public class SysLoginController {

    private final CacheManager cacheManager;
    private final TokenStore tokenStore;


    /**
     * 退出
     */
    @PostMapping(value = "/sys/logout")
    public R logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
        if (StrUtil.isBlank(authHeader)) {
            return R.ok(Boolean.FALSE, "退出失败，token 为空");
        }

        String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE.toLowerCase(), StrUtil.EMPTY).trim();
        System.out.println(tokenValue);
        OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
        if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
            return R.ok(Boolean.TRUE, "退出失败，token 无效");
        }
        // 获取用户信息
        OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(accessToken);

        // 清空access token
        tokenStore.removeAccessToken(accessToken);

        // 清空 refresh token
        OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
        tokenStore.removeRefreshToken(refreshToken);
        return R.ok();
    }

    /**
     * @return
     * @Author: guoy
     * @Param: [serverRequest]
     * @Return: reactor.core.publisher.Mono<org.springframework.web.reactive.function.server.ServerResponse>
     * @Date: 2019/12/13 11:32
     * 功能描述：滑动验证码
     */
    @GetMapping("/code")
    public R<Map<String, Object>> code(String randomStr) {

        // 原图获取流
        String primaryFormatUrl = StrUtil.format("wordCodeImg/{}", WordCodeEnum.getMessageByCode(RandomUtil.randomInt(WordCodeEnum.values().length)));
        InputStream primaryStream = ResourceUtil.getStream(primaryFormatUrl);

        // 模板图
        InputStream templaStream = ResourceUtil.getStream("wordCodeImg/templates/" + WordCodeTemplatesEnum.getMessageByCode(RandomUtil.randomInt(WordCodeTemplatesEnum.values().length)));

        //生成验证码  -- 开始
        Map<String, Object> resultMap = null;
        try {
            // 根据模板裁剪图片
            resultMap = VerifyImageUtil.pictureTemplatesCut(templaStream, primaryStream);
            //保存验证码信息
            Integer xWidth = (Integer) resultMap.get("xWidth");
            RedisUtil.set(SecurityConstants.SPRING_SECURITY_RESTFUL_IMAGE_CODE + randomStr, xWidth, SecurityConstants.CODE_TIME);
            // 移除横坐标送前端
            resultMap.remove("xWidth");
            // 新建流。
            resultMap.put("image", Base64Utils.encodeToString(IoUtil.readBytes(ResourceUtil.getStream(primaryFormatUrl))));
        } catch (Exception e) {
            log.error("ImageIO write err", e);
        }
        return R.ok(resultMap);

    }
}
